package com.hl.yyx.modules.ums.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hl.yyx.common.api.ApiData;
import com.hl.yyx.common.response.ObjectResponse;
import com.hl.yyx.common.response.Response;
import com.hl.yyx.common.response.SuccessResponse;
import com.hl.yyx.dto.IdDTO;
import com.hl.yyx.dto.QueryBuilder;
import com.hl.yyx.dto.SearchFilters;
import com.hl.yyx.modules.ums.dto.AuthMenuDTO;
import com.hl.yyx.modules.ums.mapper.UmsRoleMapper;
import com.hl.yyx.modules.ums.model.UmsAdminRole;
import com.hl.yyx.modules.ums.model.UmsRole;
import com.hl.yyx.modules.ums.model.UmsRoleMenu;
import com.hl.yyx.modules.ums.service.UmsAdminRoleService;
import com.hl.yyx.modules.ums.service.UmsRoleMenuService;
import com.hl.yyx.modules.ums.service.UmsRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author hl243695czyn
 * @since 2022-06-19
 */
@Service
public class UmsRoleServiceImpl extends ServiceImpl<UmsRoleMapper, UmsRole> implements UmsRoleService {

    @Autowired
    UmsAdminRoleService adminRoleService;

    @Autowired
    UmsRoleMenuService roleMenuService;

    @Autowired
    UmsRoleMapper umsRoleMapper;

    /**
     * 分页
     *
     * @param searchFilters
     * @return
     */
    @Override
    public Response pageList(SearchFilters<UmsRole> searchFilters) {
        Page<UmsRole> page = new Page<>(searchFilters.getPageIndex(), searchFilters.getPageSize());
        QueryWrapper<UmsRole> queryWrapper = QueryBuilder.build(searchFilters);
        return new ObjectResponse<>(new ApiData<>(page(page, queryWrapper)));
    }

    @Override
    public Response create(UmsRole umsRole) {
        save(umsRole);
        return new SuccessResponse();
    }

    @Override
    public Response updateRole(UmsRole umsRole) {
        UmsRole role = umsRoleMapper.hFindById(umsRole.getId());
        BeanUtil.copyProperties(umsRole, role);
        updateById(role);
        return new SuccessResponse();
    }

    @Override
    public Response view(IdDTO idDTO) {
        return new ObjectResponse<>(umsRoleMapper.hFindById(idDTO.getId()));
    }

    @Transactional
    @Override
    public Response delete(IdDTO idDTO) {
        umsRoleMapper.hFindById(idDTO.getId());
        // 删除用户角色表的角色
        QueryWrapper<UmsAdminRole> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdminRole::getRoleId, idDTO.getId());
        adminRoleService.remove(wrapper);
        // 删除角色菜单表的对应角色
        QueryWrapper<UmsRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UmsRoleMenu::getRoleId, idDTO.getId());
        roleMenuService.remove(queryWrapper);
        umsRoleMapper.hDeleteById(idDTO.getId());
        return new SuccessResponse();
    }

    /**
     * 授权
     *
     * @return
     */
    @Transactional
    @Override
    public Response authMenu(AuthMenuDTO authMenuDTO) {
        // 先清空之前的授权
        QueryWrapper<UmsRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UmsRoleMenu::getRoleId, authMenuDTO.getId());
        roleMenuService.remove(queryWrapper);

        List<UmsRoleMenu> roleMenuList = setRoleAndMenuRelation(authMenuDTO.getMenuIds(), authMenuDTO.getId());
        roleMenuService.saveBatch(roleMenuList);
        return new SuccessResponse();
    }

    /**
     * 根据角色id查询已分配的权限
     *
     * @return
     */
    @Override
    public Response viewAuth(IdDTO idDTO) {
        QueryWrapper<UmsRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UmsRoleMenu::getRoleId, idDTO.getId());
        List<String> menuIds = roleMenuService.list(queryWrapper.select("menu_id"))
                .stream().map(UmsRoleMenu::getMenuId).collect(Collectors.toList());
        return new ObjectResponse<>(menuIds);
    }

    /**
     * 设置角色和菜单的关联关系
     *
     * @param menuIds
     * @param roleId
     * @return
     */
    public List<UmsRoleMenu> setRoleAndMenuRelation(List<String> menuIds, String roleId) {
        List<UmsRoleMenu> roleMenuList = new ArrayList<>();
        for (String menuId : menuIds) {
            UmsRoleMenu roleMenu = new UmsRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenuList.add(roleMenu);
        }
        return roleMenuList;
    }
}
